import { requestInterceptors } from './interceptors/requestInterceptors/index'
import {
  errorResponseInterceptors,
  responseInterceptors
} from './interceptors/responseInterceptors/index'
import type { AxiosInstance } from 'axios'
import type {
  IAxiosRequestConfig,
  IInternalAxiosRequestConfig,
  IResult,
  UploadFileParams
} from '@/utils/http/type'
import axios from 'axios'
import { ContentTypeEnum } from '@/utils/http/type'

export default class Http {
  private axiosInstance: AxiosInstance
  constructor(options: IAxiosRequestConfig) {
    this.axiosInstance = axios.create(options)
    this.interceptorsRequest()
    this.interceptorsResponse()
  }
  //请求拦截器
  private interceptorsRequest() {
    this.axiosInstance.interceptors.request.use(
      (config: IInternalAxiosRequestConfig) => {
        return requestInterceptors(config)
      },
      (error: any) => {
        console.log(error, 'error123')
        return Promise.reject(error)
      }
    )
  }
  //响应拦截器
  private interceptorsResponse() {
    this.axiosInstance.interceptors.response.use((response) => {
      return responseInterceptors(response)
    }, errorResponseInterceptors)
  }
  request<T = any>(config: IAxiosRequestConfig): Promise<IResult<T>> {
    return this.axiosInstance.request(config)
  }

  get<T = any>(option: IAxiosRequestConfig): Promise<IResult<T>> {
    return this.request({ method: 'GET', ...option })
  }

  post<T = any>(option: IAxiosRequestConfig): Promise<IResult<T>> {
    return this.request({ method: 'POST', ...option })
  }

  put<T = any>(option: IAxiosRequestConfig): Promise<IResult<T>> {
    return this.request({ method: 'PUT', ...option })
  }

  delete<T = any>(option: IAxiosRequestConfig): Promise<IResult<T>> {
    return this.request({ method: 'DELETE', ...option })
  }
  /**
   * 上传文件
   * @param params
   */
  uploadFile<T = any>(params: UploadFileParams) {
    const formData = new window.FormData()
    const customFilename = params.name || 'file'

    if (params.filename) {
      formData.append(customFilename, params.file, params.filename)
    } else {
      formData.append(customFilename, params.file)
    }

    if (params.data) {
      Object.keys(params.data).forEach((key) => {
        const value = params.data![key]
        if (Array.isArray(value)) {
          value.forEach((item) => {
            formData.append(`${key}[]`, item)
          })
          return
        }

        formData.append(key, params.data![key])
      })
    }

    return this.request<T>({
      method: 'POST',
      data: formData,
      headers: {
        'Content-type': ContentTypeEnum.FORM_DATA,
        ignoreCancelToken: true
      }
    })
  }
}
